package com.sojson.config.converter;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sojson.constant.Constant;
import com.sojson.util.DateUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 自定义全局转换器
 * 
 * @author liu
 * @date 2021-04-23
 */
@Slf4j
@Configuration
public class CustomConverter {

    /**
     * 高版本的Tomcat无法接收特殊字符的参数,需要加上这个
     * 
     * @return
     */
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers(
            (TomcatConnectorCustomizer)connector -> connector.setProperty("relaxedQueryChars", "|{}[]\\"));
        log.info("TomcatServletWebServerFactory注入成功,高版本的Tomcat无法接收特殊字符的参数,需要加上这个！");
        return factory;
    }

    /**
     * 配置消息转换器<BR/>
     * (只对@RequestBody和@ResponseBody有用)<BR/>
     * new HttpMessageConverters(true, converters); 
     * 一定要设为true才能替换否则不会替换
     * @return 返回一个消息转换的bean<BR/>
     */
    @Bean
    public HttpMessageConverters fastJsonMessageConverters() {
        List<HttpMessageConverter<?>> converters = new ArrayList<>();

        // 需要定义一个convert转换消息的对象;
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // 添加fastJson的配置信息;
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        // 全局时间配置
        JSON.DEFFAULT_DATE_FORMAT = DateUtil.YYYY_MM_DD_HHFMMFSS_STR;
        // 下面这种方式会覆盖掉@JSONField(format = "yyyy-MM-dd"),所以不用
        // fastJsonConfig.setDateFormat(DateUtil.YYYY_MM_DD_HHFMMFSS_STR);
        // 字符集
        fastJsonConfig.setCharset(Charset.forName(Constant.DEFAULT_ENCODING));
        // FastJson配置
        // SerializerFeature.DisableCircularReferenceDetect解决循环引用问题
        // SerializerFeature.WriteMapNullValue:如果不设置,某个字段为null的话就不显示,json对象就没有这个属性
        // fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect,
        // SerializerFeature.WriteDateUseDateFormat);
        fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect,
            SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
        // 处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON);
        // 在convert中添加配置信息.
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(0, fastConverter);
        log.info("消息转换器FastJsonHttpMessageConverter注入成功！");

        return new HttpMessageConverters(converters);
    }

    /**
     * 修改默认消息转换器<BR/>
     * (只对@RequestBody和@ResponseBody有用)<BR/>
     * 
     * @param objectMapper
     * @return
     */
    // @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {

        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter =
            new MappingJackson2HttpMessageConverter();
        objectMapper.setDateFormat(new SimpleDateFormat(DateUtil.YYYY_MM_DD_HHFMMFSS_STR));
        mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
        log.info("默认消息转换器MappingJackson2HttpMessageConverter修改成功！");

        return mappingJackson2HttpMessageConverter;
    }

}